The way in which you define auto-destruct classes has changed. The new way to make a class be an autodestruct object is to use the FW_DECLARE_AUTO(className) macro in the class definition, and the FW_DEFINE_AUTO(className) macro in the .cpp file that contains the constructors and destructor for the class. These macros are similar to the FW_DECLARE_CLASS and FW_DEFINE_CLASS macros used for RTTI, with the difference that FW_DECLARE_AUTO requires the class name parameter.
Old way:
class CFoo FW_AUTO_DESTRUCT_OBJECT
{
public:
...
};
New way:
class CFoo
{
public:
FW_DECLARE_AUTO(CFoo)
...
};
The FW_DEFINE_AUTO macro should be added to the .cpp file before the first constructor:
FW_DEFINE_AUTO(CFoo)
// CFoo constructor follows
If you subclass an auto-destruct class, you must add the two macros to your derived class. If you forget them you’ll get cryptic link errors when you build. The following ODF classes are all auto-destruct classes:
many view subclasses: FW_CButton, FW_CEditView, FW_CListBox, FW_CStaticText, etc.
Remember that you must use FW_NEW instead of new to instantiate an auto-destruct class.
Auto-destruct objects may now inherit from more than one auto-destruct base class. Note that auto-destruct objects no longer need have a virtual destructor, so they may be lightweight objects without vtables.
See “Using Auto-Destruct Classes” in chapter 9 of the ODF Developer’s Guide for details on auto-destruct classes and how to use them.
Collections
Collections and their iterators are now template-based.
• Old way to iterate elements of a collection:
FW_CPrivOrderedCollection* xxxList;
FW_COrderedCollectionIterator it(xxxList);
for (CXxx* theXxx = (CXxx*)it.First(); it.IsNotComplete(); theXxx = (CXxx*)it.Next())
• New way:
CXxxCollection* xxxList;
CXxxCollectionIterator ite(xxxList);
for (CXxx* theXxx = it.First(); it.IsNotComplete(); theXxx = it.Next())
• Here is a “template” (pun intended) for a collection class definition (in .h file):
class CXxxCollection : public FW_TOrderedCollection<CXxx>
{
public:
FW_DECLARE_AUTO(CXxxCollection)
CXxxCollection() :
FW_TOrderedCollection<CXxx>(){}
~CXxxCollection() {}
};
• Here is a “template” for an iterator class definition (in .h file):
class CXxxCollectionIterator : public FW_TOrderedCollectionIterator<CXxx>
• In your .cpp file you should force the template classes to be instantiated like this:
FW_DEFINE_AUTO(CXxxCollection)
FW_DEFINE_AUTO(CXxxCollectionIterator)
Exception Handling
Exception objects are no longer derived from an implementation base class. The FW_EXCEPTION_OBJECT macro is no longer used and is intentionally undefined. However, any users who defined their own base exception classes will probably not need to make any changes other than removing the use of the FW_EXCEPTION_OBJECT, and possibly using FW_DECLARE_EXCEPTION and FW_DEFINE_EXCEPTION.
See the Engineering Note “Exceptions/RTTI” for more information.
Macros
A number of macros have become obsolete.
• FW_AUTO_DESTRUCT_OBJECT and FW_AUTO_DESTRUCT_MIXIN (see “Auto-destruct objects”, above)
• Remove all FW_CLASS_ATTR and FW_FUNC_ATTR macros.
• FW_EXCEPTION_OBJECT (see “Exception Handling”, above)
• Remove all FW_LIB_EXPORT_PRAGMAS.
Old style (from DrawFrm.h in the Draw sample):
#if FW_LIB_EXPORT_PRAGMAS
#pragma import on
#endif
class FW_CLASS_ATTR FW_CPresentation;
class FW_CLASS_ATTR FW_CGrowBox;
#if FW_LIB_EXPORT_PRAGMAS
#pragma import off
#endif
class FW_CLASS_ATTR CDrawPart;
class FW_CLASS_ATTR CDrawSelection;
class FW_CLASS_ATTR FW_CRuler;
New style:
class FW_CPresentation;
class FW_CGrowBox;
class CDrawPart;
class CDrawSelection;
class CRuler;
I think it looks a lot better, don’t you?
SOMnification and Shared Library
A number of classes in the Foundation and OS layers were converted to SOM classes. In addition, much of the code in the Foundation and OS layers was moved to the ODF shared library. Not to worry, ODF provides wrapper classes that you can use in ODF 1. Here is a list of those classes and the name of the class to use instead:
See the document “ODF Shared Library” for an explanation of wrapper classes and the shared library.
An Environment* argument has been added to most of the constructors for these classes. For example, compare this fragment from CScriptAction::InternalizeScriptFile in the Button part:
• ODF 1 provides a more efficient mechanism to access the Environment variable when there is no ev parameter. Instead of calling somGetGlobalEnvironment, you can use the class FW_SOMEnvironment to declare an ev on the stack. Simply replace this line:
Environment* ev = somGetGlobalEnvironment();
with this line:
FW_SOMEnvironment ev;
Storage Units and Archiving
There are some picky little API changes in the storage unit streaming classes. For example, the name of FW_CStorageUnitSink has been changed to FW_PStorageUnitSink. Environment variables have been added in a few places, too.
Writing to a StorageUnit
Old way to write a proxy (in CMyPart::ExternalizeContent):
The archiver and all archiving functions were changed to provide better support for view editors. Now, all archiving functions take an extra argument which is the "type constant" identifying the class of the object being created from the stream. This makes it possible to write one set of four "wild card" archiving functions that could be used with many classes.
The four archiving functions now have the following prototypes:
Note that the FW_REGISTER_ARCHIVABLE_CLASS macro has two additional parameters, for the initialize and destroy functions.
See the chapter on Streams in the ODF Class Reference for more information.
Strings
The string classes have been re-org’ed and moved to the ODF shared library. The string class hierarchy has been simplified; the classes FW_CByteString, FW_CDynamicString, and FW_CIntlString are gone. Simply use FW_CString for everything. If you want to use a bounded string, FW_CString32 and FW_CString255 are still available.
The operator const char*() was removed, so in order to get a C (null-terminated) string from an FW_CString it is now necessary to explicitly export one using the method ExportCString.
Archiving Strings
The special classes for archiving strings (FW_CStringArchiver, FW_CDynamicStringArchiver, etc.) have all been removed. To read a string, simply stream it from an FW_CReadableStream: